package co.edu.uniandes.ecos.itera.tsp.interfaz;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DateFormat;
import java.text.SimpleDateFormat;


import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.WindowConstants;

import javax.swing.JTextField;
import javax.swing.border.TitledBorder;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;

import co.edu.uniandes.ecos.itera.tsp.anotaciones.Avance;
import co.edu.uniandes.ecos.itera.tsp.anotaciones.Avances;
import co.edu.uniandes.ecos.itera.tsp.anotaciones.Loc;
import co.edu.uniandes.ecos.itera.tsp.anotaciones.Tiempos;
import co.edu.uniandes.ecos.itera.tsp.anotaciones.LogT;
import co.edu.uniandes.ecos.itera.tsp.mundo.Ciclo;

import co.edu.uniandes.ecos.itera.tsp.mundo.Defecto;
import co.edu.uniandes.ecos.itera.tsp.mundo.DelegadoNegocio;
import co.edu.uniandes.ecos.itera.tsp.mundo.PlanCalidad;
import co.edu.uniandes.ecos.itera.tsp.mundo.Etapa;
import co.edu.uniandes.ecos.itera.tsp.mundo.Proyecto;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;

@Avances({
	@Avance(taskId=68, termino='S'),
	@Avance(taskId=84, termino='S')
})
@Tiempos({
	@LogT(date="2011-03-20", min=33, taskId=68),
	@LogT(date="2011-03-26", min=88, taskId=68)
})
public class ManejarCiclo extends JPanel implements ActionListener{
	/**
	 * Referencia al objeto que permite trabajar las transacciones de negocio
	 */
	private DelegadoNegocio accesoAMundo;
	
	/**
	 * Ciclo que se esta trabajando en estos momentos en esta pantalla
	 */
	private Ciclo cicloTrabajandose;
	
	/**
	 * Proyecto al cual pertenece este Ciclo
	 */
	private Proyecto proyectoContenedor;

	/**
	 * Referencia al objeto contenedor. Este es el objeto
	 * que maneja la pantalla principal, o sea el admon de proyectos
	 */
	private MenuPrincipal referenciaAContenedor;
	
	/**
	 * Determina como unico a este objeto
	 */
	private static final long serialVersionUID = 1L;
	
	/**
	 * Constante para definir la accion de almacenar
	 */
	private static final String ALMACENAR = "Almacenar";
	
	private JTextField txtNumeroCiclo;
	private JTextField txtFechaInicial;
	private JTextField txtFechaFin;
	private JTable tbPlanCalidad;
	private String[] nombresColumnas = {"Etapa", "Defectos Inyectados", "Defectos Removidos"};
	private Object[][] datosTabla;
	
	/**
	 * Consutrctor por defecto
	 * @param mundo Referencia al objeto que permite trabajar las transacciones de negocio
	 */
	@LogT(date="2011-03-20", min=144, taskId=84)
	public ManejarCiclo(DelegadoNegocio mundo, MenuPrincipal contenedor, Proyecto proyectoContenedor)
	{
		this.accesoAMundo = mundo;
		this.referenciaAContenedor = contenedor;
		this.cicloTrabajandose = null;
		this.proyectoContenedor = proyectoContenedor;
		
		this.pintarse();
	}

	/**
	 * Se encarga de pintar los elementos de la pantalla
	 */
	@Loc(size=30, taskId=84)
	private void pintarse()
	{				
		setLayout(null);
		
		JLabel lblNumCiclo = new JLabel();
		add(lblNumCiclo);
		lblNumCiclo.setText("Numero Ciclo");
		lblNumCiclo.setBounds(27, 20, 88, 16);
		
		txtNumeroCiclo = new JTextField();
		add(txtNumeroCiclo);
		txtNumeroCiclo.setBounds(171, 17, 75, 23);
		
		JLabel lblFechaInicio = new JLabel();
		add(lblFechaInicio);
		lblFechaInicio.setText("Fecha de Inicio");
		lblFechaInicio.setBounds(27, 48, 95, 16);
		
		txtFechaInicial = new JTextField();
		add(txtFechaInicial);
		txtFechaInicial.setBounds(171, 45, 74, 23);
		
		JLabel lblFechaFinal = new JLabel();
		add(lblFechaFinal);
		lblFechaFinal.setText("Fecha de Finalizacion");
		lblFechaFinal.setBounds(27, 76, 132, 16);
		
		txtFechaFin = new JTextField();
		add(txtFechaFin);
		txtFechaFin.setBounds(171, 73, 74, 23);
		
		JLabel lblPlanCalidad = new JLabel();
		add(lblPlanCalidad);
		lblPlanCalidad.setText("Plan de Calidad de este Ciclo");
		lblPlanCalidad.setBounds(27, 104, 182, 16);
		
		datosTabla = new Object[Etapa.values().length][3];
		int f = 0;
		for(Etapa etapa: Etapa.values())
		{
			datosTabla[f][0] = etapa.toString();
			datosTabla[f][1] = "0";
			datosTabla[f][2] = "0";
			
			f++;
		}
		
		tbPlanCalidad = new JTable();
		add(tbPlanCalidad);
		tbPlanCalidad.setBounds(27, 126, 304, 207);
		tbPlanCalidad.setOpaque(false);
		
		TableModel modeloTabla = new DefaultTableModel(datosTabla, nombresColumnas);
		tbPlanCalidad.setModel(modeloTabla);
		
		
		JButton btnAlmacenar = new JButton();
		add(btnAlmacenar);
		btnAlmacenar.setText("Almacenar");
		btnAlmacenar.setBounds(27, 339, 109, 23);
		btnAlmacenar.setActionCommand(ALMACENAR);
		btnAlmacenar.addActionListener(this);
	}

	/**
	 * Almacena el Defecto, ya sea creado o modificado
	 */
	@Loc(size=57, taskId=84)
	public void almacenar()
	{
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		
		if(this.txtNumeroCiclo.getText().trim().length() == 0 ||
		   this.txtFechaInicial.getText().trim().length() == 0 ||
		   this.txtFechaFin.getText().trim().length() == 0)
		{
			JOptionPane.showMessageDialog(null, "Debe proveer los datos que se le estan preguntando", "Error", JOptionPane.ERROR_MESSAGE);
		}
		else
		{
			try
			{
				if(this.cicloTrabajandose == null) // si se esta creando un Ciclo
				{
					int idCiclo = Integer.parseInt(this.txtNumeroCiclo.getText().trim());
					
					Date fechaInicio = sdf.parse(this.txtFechaInicial.getText());
					Date fechaFin = sdf.parse(this.txtFechaFin.getText());
					
					this.cicloTrabajandose = new Ciclo();
					this.cicloTrabajandose.setNumeroCiclo(idCiclo);
					this.cicloTrabajandose.setFechaInicio(fechaInicio);
					this.cicloTrabajandose.setFechaFin(fechaFin);
					
					ArrayList<PlanCalidad> planCalidad = new ArrayList<PlanCalidad>();
					
					int numEtapas = Etapa.values().length;
					for(int f=0; f<numEtapas; f++)
					{
						boolean etapaEncontrada = false;
						Etapa etapa = Etapa.DESARROLLO;
						
						String nombreEtapa = this.tbPlanCalidad.getValueAt(f, 0).toString();
						int inyectados = Integer.parseInt(this.tbPlanCalidad.getValueAt(f, 1).toString().trim());
						int removidos = Integer.parseInt(this.tbPlanCalidad.getValueAt(f, 2).toString().trim());
						
						for(Etapa e: Etapa.values())
						{
							if(e.toString().trim().toLowerCase().contains(nombreEtapa.trim().toLowerCase()))
							{
								etapa = e;
								etapaEncontrada = true;
								break;
							}
						}
						
						if(!etapaEncontrada)
							continue;
						
						PlanCalidad pc = new PlanCalidad();
						pc.setEtapa(etapa);
						pc.setInyectados(inyectados);
						pc.setRemovidos(removidos);
						
						planCalidad.add(pc);
					}
					
					this.cicloTrabajandose.setPlanCalidad(planCalidad);
					this.proyectoContenedor.agregarCiclo(cicloTrabajandose);
				}
				else // Si ya existe el defecto
				{
					int idCiclo = Integer.parseInt(this.txtNumeroCiclo.getText().trim());
					
					Date fechaInicio = sdf.parse(this.txtFechaInicial.getText());
					Date fechaFin = sdf.parse(this.txtFechaFin.getText());
					
					this.cicloTrabajandose.setNumeroCiclo(idCiclo);
					this.cicloTrabajandose.setFechaInicio(fechaInicio);
					this.cicloTrabajandose.setFechaFin(fechaFin);
					
					ArrayList<PlanCalidad> planCalidad = new ArrayList<PlanCalidad>();
					
					int numEtapas = Etapa.values().length;
					for(int f=0; f<numEtapas; f++)
					{
						boolean etapaEncontrada = false;
						Etapa etapa = Etapa.DESARROLLO;
						
						String nombreEtapa = this.tbPlanCalidad.getValueAt(f, 0).toString();
						int inyectados = Integer.parseInt(this.tbPlanCalidad.getValueAt(f, 1).toString().trim());
						int removidos = Integer.parseInt(this.tbPlanCalidad.getValueAt(f, 2).toString().trim());
						
						for(Etapa e: Etapa.values())
						{
							if(e.toString().trim().toLowerCase().contains(nombreEtapa.trim().toLowerCase()))
							{
								etapa = e;
								etapaEncontrada = true;
								break;
							}
						}
						
						if(!etapaEncontrada)
							continue;
						
						PlanCalidad pc = new PlanCalidad();
						pc.setEtapa(etapa);
						pc.setInyectados(inyectados);
						pc.setRemovidos(removidos);
						
						planCalidad.add(pc);
					}
					
					this.cicloTrabajandose.setPlanCalidad(planCalidad);
				}
				
				JOptionPane.showMessageDialog(null, "Ciclo almacenado exitosamente", "Exito", JOptionPane.INFORMATION_MESSAGE);
				
				this.referenciaAContenedor.cargarArbol();
			}
			catch(Exception ex)
			{
				JOptionPane.showMessageDialog(null, "Error al almacenar ciclo: " + ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
			}
		}
	}

	/**
	 * Se encarga de cargar El defecto en pantalla para
	 * poderlo manejar por el usuario
	 * @param defectoACargar Informacion del defecto que se desea actualizar
	 */
	@Loc(size=17, taskId=84)
	public void cargarEntidades(Ciclo cicloACargar)
	{
		this.cicloTrabajandose = cicloACargar;
		
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		
		this.txtNumeroCiclo.setText("" + this.cicloTrabajandose.getNumeroCiclo());
		this.txtFechaInicial.setText(sdf.format(this.cicloTrabajandose.getFechaInicio()));
		this.txtFechaFin.setText(sdf.format(this.cicloTrabajandose.getFechaFin()));
		
		this.datosTabla = new Object[this.cicloTrabajandose.getPlanCalidad().size()][3];
		int f = 0;
		for(PlanCalidad pc: this.cicloTrabajandose.getPlanCalidad())
		{
			this.datosTabla[f][0] = pc.getEtapa().toString();
			this.datosTabla[f][1] = "" + pc.getInyectados();
			this.datosTabla[f][2] = "" + pc.getRemovidos();
			f++;
		}
		
		TableModel modeloTabla = new DefaultTableModel(datosTabla, nombresColumnas);
		tbPlanCalidad.setModel(modeloTabla);
		this.tbPlanCalidad.updateUI();
	}

	/**
	 * Acciones a realizar en la pantalla
	 */
	@Override
	@Loc(size=3, taskId=84)
	public void actionPerformed(ActionEvent e) 
	{
		String comando = e.getActionCommand( );

        if( comando.equals(ALMACENAR) )
            this.almacenar();
	}

}
